package com.zy.rushjdcloud.service.impl;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.zy.rushjdcloud.service.ScheduledService;
import com.zy.rushjdcloud.task.ScheduledTask;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.*;

/**
 * @author zy
 * @date 2019-10-4 11:36
 */
@Service
public class ScheduledServiceImpl implements ScheduledService, InitializingBean{

    private static ScheduledExecutorService service;

    private static Map<String, ScheduledFuture> futureMap = new ConcurrentHashMap<>();

    @Override
    public boolean addTask(ScheduledTask scheduledTask) {
        if (futureMap.get(scheduledTask.getTaskId()) != null) {
            return false;
        }
        // 这里将任务放入定时服务中
        ScheduledFuture<?> scheduledFuture = service.scheduleWithFixedDelay(scheduledTask.getRunnable()
                , scheduledTask.getInitialDelay(), scheduledTask.getDelay(), TimeUnit.MILLISECONDS);

        futureMap.put(scheduledTask.getTaskId(),scheduledFuture);
        return true;
    }

    @Override
    public boolean updateTask(ScheduledTask scheduledTask) throws InterruptedException {
        if (futureMap.get(scheduledTask.getTaskId()) == null) {
            return false;
        }
        // 先停止
        remove(scheduledTask.getTaskId());
        // 再添加
        addTask(scheduledTask);
        return true;
    }

    @Override
    public boolean remove(String taskId) {
        if (futureMap.get(taskId) == null) {
            return false;
        }
        ScheduledFuture scheduledFuture = futureMap.get(taskId);
        scheduledFuture.cancel(false);
        futureMap.remove(taskId);
        return true;
    }

    @Override
    public boolean exists(ScheduledTask scheduledTask) {
        return futureMap.get(scheduledTask.getTaskId()) != null;
    }

    @Override
    public void shutdown() {
        service.shutdown();
    }

    @Override
    public void init() throws Exception {
        afterPropertiesSet();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 初始化
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("schedule-pool-%d").setDaemon(true).build();
        if (service != null) {
            service.shutdown();
        }
        service = new ScheduledThreadPoolExecutor(2, threadFactory, new ThreadPoolExecutor.AbortPolicy());
    }
}
